#!/bin/sh -x

# TODO - allow combinations of remove styles with show styles

# ----------------------------------------------------------------------------
#
#
# 	REMOVE_BIN=$1
#   REMOVE_ACTION=$2
#   REMOVE_VOL=$3
#	REMOVE_SHOW_ONLY=$4
#
function defineRemoveArgs()
{
	if [ -z "$1" ]
	then
		echo "No bin dir specified"
		exit 1
	fi
	
	REMOVE_BIN="$1"
	REMOVE_ACTION="$2"
	REMOVE_VOL="$3"
	REMOVE_SHOW_ONLY="$4"
	
	if [ -z "${REMOVE_ACTION}" ]
	then
		REMOVE_ACTION="trash"
	fi
}

# ----------------------------------------------------------------------------
function showRemoveArgs()
{
	echo "    REMOVE_BIN=${REMOVE_BIN}"					> /dev/stderr
	echo "    REMOVE_ACTION=${REMOVE_ACTION}"			> /dev/stderr
	echo "    REMOVE_VOL=${REMOVE_VOL}"					> /dev/stderr
	echo "    REMOVE_SHOW_ONLY=${REMOVE_SHOW_ONLY}"		> /dev/stderr
	echo "    " > /dev/stderr

}

# ----------------------------------------------------------------------------

function bailOnError()
{
	if test "$1" -ne 0; then
		echo "$2" > /dev/stderr
		exit 1
	fi
}

# ----------------------------------------------------------------------------

function validateTool()
{
	if ! [ -z "$1" ]
	then
		if ! [ -x "$1" ]
		then
			echo "$1 is not executable"
			exit 1
		fi
	fi
}

# ----------------------------------------------------------------------------
#
# Take $1 $2 and $3 and convert to
# 	PACKAGE_NAME, VARIANT, VOLUME, and INSTALLER_TOOLS_DIR
#	$1 is expected to be the full path to the installer .pkg
#
#

function locateTools()
{
	if [ -z "${REMOVE_BIN}" ]
	then
		echo "No removal bin defined" > /dev/stderr
		exit 1
	fi

	# Trash Tool
	TRASH_TOOL="${REMOVE_BIN}/MoveToTrash"
	if ! [ -x "${TRASH_TOOL}" ]
	then
		TRASH_TOOL=""
	fi
	
	# Locate MvMac if available, look in Developer/Tools and REMOVE_BIN
	MVMAC="/Developer/Tools/MvMac"
	if ! [ -x "${MVMAC}" ]
	then
		MVMAC="${REMOVE_BIN}/MvMac"
	fi
	if ! [ -x "${MVMAC}" ]
	then
		MVMAC=""
	fi
	
	# If no trash tool, the action is remove
	
	if [[ -z "${TRASH_TOOL}" && -z "${MVMAC}" && "${REMOVE_ACTION}" == "trash" ]]
	then
		REMOVE_ACTION="remove"
	fi
	
	# If 10.2 or earlier, the action is remove, Trash tool uses a function only available
	# in 10.3 and later.
	IsPre10_3
	if [ $? -ne 0 ]
	then
		REMOVE_ACTION="remove"
	fi
	
	# Locate rm
	RM="/bin/rm -rf"
	
	# Define the trash dir
	TRASH_DIR="~/.Trash"
	
# 	echo "TRASH_DIR=${TRASH_DIR}"

	# Make sure the trash directory is writable
	# TODO - why does this fail?!
#	if ! [ -d "${TRASH_DIR}" ]
#	then
#		echo "'${TRASH_DIR}' is not a directory"
#		# exit 1
#	fi
#	if ! [ -w "${TRASH_DIR}" ]
#	then
#		echo "'${TRASH_DIR}' is not writable"
#		# exit 1
#	fi

	KILL_DEVICE_MONITOR="${REMOVE_BIN}/KillDeviceMonitor"
	KILL_SESSION_MONITOR="${REMOVE_BIN}/KillSessionMonitor"
	COMPONENT_TOOL="${REMOVE_BIN}/ComponentTool"
	
#	validateTool "${KILL_DEVICE_MONITOR}"
#	validateTool "${KILL_SESSION_MONITOR}"
#	validateTool "${COMPONENT_TOOL}"
	
}

# ----------------------------------------------------------------------------
# defineInstallLocations
# 	expects VOLUME to be defined
#
#	defines the following directories
#		APPLICATION_SUPPORT_DIR
#		APPLICATION_SUPPORT_BIN_DIR
#		APPLICATION_DIR
#		COMPONENTS_DIR
#		SYSTEM_EXTENSIONS_DIR
#		STARTUP_ITEMS
#		SYSTEM_STARTUP_ITEMS
#		PREFERENCES_DIR
#		HOME_PREFERENCES_DIR
#

function defineInstallLocations()
{
	VENDOR_SUBDIR="$1"
	VENDOR_APP_SUBDIR="$2"
	APPLICATION_SUPPORT_DIR="${VOLUME}/Library/Application Support/${VENDOR_SUBDIR}"
	APPLICATION_SUPPORT_BIN_DIR="${APPLICATION_SUPPORT_DIR}/Private"
	APPLICATION_SUPPORT_BIN_DIR_OLD="${APPLICATION_SUPPORT_DIR}/bin"
	APPLICATION_SUPPORT_BIN_DIR_OLD_2="${APPLICATION_SUPPORT_DIR}/Applications"
	APPLICATION_DIR="${VOLUME}/Applications/${VENDOR_APP_SUBDIR}"
	COMPONENTS_DIR="${VOLUME}/Library/Components"
	SYSTEM_EXTENSIONS_DIR="${VOLUME}/System/Extensions"
	STARTUP_ITEMS="${VOLUME}/Library/StartupItems"
	SYSTEM_STARTUP_ITEMS="${VOLUME}/System/Library/StartupItems"
	PREFERENCES_DIR="${VOLUME}/Library/Preferences"
	HOME_PREFERENCES_DIR="~/Library/Preferences"
	RECEIPTS_DIR="${VOLUME}/Library/Receipts"
	IMAGE_CAPTURE_DIR="${VOLUME}/System/Library/Image Capture/Devices"
}

# ----------------------------------------------------------------------------
function moveToTrash()
{
	if ! [ -z "${TRASH_TOOL}" ]
	then
		if [ "${REMOVE_SHOW_ONLY}" != 0 ]
		then
			echo "${TRASH_TOOL}" "$1"
		else
			"${TRASH_TOOL}" "$1"
		fi
		return 0
	fi
	return 1
}

# ----------------------------------------------------------------------------
function mvMacToTrash()
{
	if ! [ -z "${MVMAC}" ]
	then
		if [ "${REMOVE_SHOW_ONLY}" != 0 ]
		then
			echo "${MVMAC}" "$1" "${TRASH_DIR}"
		else
			"${MVMAC}" "$1" "${TRASH_DIR}"
		fi
		return 0
	fi
	return 1
}

# ----------------------------------------------------------------------------
function remove()
{
	if [ "${REMOVE_SHOW_ONLY}" != 0 ]
	then
		echo ${RM} "$1"
	else
		${RM} "$1"
	fi
	return 0
}

# ----------------------------------------------------------------------------
function removeAction()
{
	if [ -e "$1" ]
	then
		if [ "${REMOVE_ACTION}" == "trash" ]
		then
			moveToTrash "$1"
			if test $? -ne 0
			then
				mvMacToTrash "$1"
			fi
		
		elif [ "${REMOVE_ACTION}" == "mvmac" ]
		then
			mvMacToTrash "$1"
		
		elif [ "${REMOVE_ACTION}" == "remove" ]
		then
			remove "$1"
		
		elif [ "${REMOVE_ACTION}" == "show" ]
		then
			echo "$1"
		
		else
			echo "Unknown action in remove function"
			exit 1
		fi
		
		if test $? -ne 0
		then
			echo "${REMOVE_ACTION} failed for $1"
		fi
		
	fi
}

# ----------------------------------------------------------------------------
function removeActionVariants()
{
	removeAction "$1$2"
	removeAction "$1-Debug$2"
	removeAction "$1-Logging$2"
}

# ----------------------------------------------------------------------------
function removeActionGlob()
{
	local FILES=`ls -1 $1 2>/dev/null`
	
	for name in ${FILES}
	do
		# echo "FOUND: ${name}"
		removeAction "${name}"
	done
}

# ----------------------------------------------------------------------------
function removeActionCustomizedComponents()
{
	local FILES=`"${COMPONENT_TOOL}" -showcustomized "$1" "$2" "$3" "$4" "$5" "$6"`
	
	for name in ${FILES}
	do
		# echo "FOUND: ${name}"
		removeAction "${name}"
	done
}


# ----------------------------------------------------------------------------
function killDeviceMonitor()
{

	if ! [ -z "${KILL_DEVICE_MONITOR}" ]
	then
		if [[ "${REMOVE_ACTION}" == "trash"  || "${REMOVE_ACTION}" == "mvmac" ||  "${REMOVE_ACTION}" == "remove" ]]
		then
			if [ "${REMOVE_SHOW_ONLY}" != 0 ]
			then
				echo "'${KILL_DEVICE_MONITOR}'"
			else
				echo "Stopping Device Monitor..."
				"${KILL_DEVICE_MONITOR}" "$1"
				local rv=$?
				if test "${rv}" -gt 1; then
					bailOnError ${rv} "${KILL_DEVICE_MONITOR} failed"
				fi
			fi
		
		elif [[ "${REMOVE_ACTION}" == "show" ]]
		then
			echo "'${KILL_DEVICE_MONITOR}'"

		else
			echo "Unknown action in killDeviceMonitor function"
			exit 1
		fi
	else
		echo "   TODO - try killall to kill device monitor" > /dev/stderr
	fi
}

# ----------------------------------------------------------------------------
function killSessionMonitor()
{
	
	if ! [ -z "${KILL_SESSION_MONITOR}" ]
	then
		if [[ "${REMOVE_ACTION}" == "trash"  || "${REMOVE_ACTION}" == "mvmac" ||  "${REMOVE_ACTION}" == "remove" ]]
		then
			if [ "${REMOVE_SHOW_ONLY}" != 0 ]
			then
				echo "'${KILL_SESSION_MONITOR}'"
			else
				echo "Stopping Session Monitor..."
				"${KILL_SESSION_MONITOR}"
				local rv=$?
				if test "${rv}" -gt 1; then
					bailOnError ${rv} "${KILL_SESSION_MONITOR} failed"
				fi
			fi
		
		elif [[ "${REMOVE_ACTION}" == "show" ]]
		then
			echo "'${KILL_SESSION_MONITOR}'"

		else
			echo "Unknown action in killSessionMonitor function"
			exit 1
		fi
	else
		echo "   TODO - try killall to killSessionMonitor" > /dev/stderr
	fi
}


# ----------------------------------------------------------------------------
function killRegisterApp()
{
	echo "    TODO - stop Register App..." > /dev/stderr
	# 
	# if ! [ -z "${KILL_SESSION_MONITOR}" ]
	# then
	# 		"${KILL_SESSION_MONITOR}"
	#		local rv=$?
	#		if test "${rv}" -gt 1; then
	#			bailOnError ${rv} "${KILL_SESSION_MONITOR} failed"
	#		fi
	#else
	#	echo "   TODO - try killall to kill device monitor" > /dev/stderr
	#fi
}

# ----------------------------------------------------------------------------
# 0 if not dir or not empty
# 1 if empty

function isDirEmpty()
{
	# echo "isDirEmpty($1)"
	if [ -z "$1" ]
	then
		return 0
	fi

	if [ -d "$1" ]
	then
		local count=0
		local items=`ls -1A "$1" | sed -e 's/.DS_Store//'`
		# echo "isDirEmpty($1) - contents = '${items[@]}'"
		for name in  "${items[@]}"
		do
			# echo "CONTENTS-${name}-"
			if ! [ -z "${name}" ]
			then
				let count=count+1
			fi
		done
		# echo COUNT=${count}
		if test ${count} -eq 0
		then
			return 1
		fi
	fi
	return 0
}

# ----------------------------------------------------------------------------
# rm -rf "$1" if an empty directory (.DS_Store allowed)

function removeEmptyDir()
{
	# set -x
	isDirEmpty "$1"
	if test $? -ne 0
	then
		echo "Removing empty directory $1"
		removeAction "$1"
	fi
	# set +x
}

# ----------------------------------------------------------------------------
# 0 if not dir or not empty

function countDir()
{
	local count=0
	if [ -d "$1" ]
	then
		local items=`ls -1A "$1" | sed -e 's/.DS_Store//'`
		for name in  "${items[@]}"
		do
			let count=count+1
		done
	fi
	return ${count}
}

# ----------------------------------------------------------------------------
# returns nonzero if receipt found

function checkForReceipt()
{
	local items=`ls -1A "${RECEIPTS_DIR}/$1.pkg" 2>/dev/stderr`
	local count=0
	for name in  "${items[@]}"
	do
		let count=count+1
	done
	return ${count}
}


# ----------------------------------------------------------------------------
# Determine whether we are 10.2 and earlier or not
# returns nonzero if pre 10.3

function IsPre10_3()
{
	local PRE_10_3=1
	if [ -x "/usr/bin/sw_vers" ]
	then
		local _V=`/usr/bin/sw_vers | grep ProductVersion | sed -e 's/ProductVersion:[^0-9]*//'`
		local maj=`echo ${_V} | sed -e 's/\..*//'`
		local min=`echo ${_V} | sed -e 's/[0-9]*\.//' -e 's/\..*//'`
		# echo V ${_V}
		# echo "MAJ '${maj}'"
		# echo "MIN '${min}'"

		if  [ ${maj} -gt 10 ]
		then
			PRE_10_3=0
		elif [[ ${maj} -eq 10 && ${min} -gt 2 ]]
		then
			PRE_10_3=0
		fi
	fi
	return ${PRE_10_3}
}

# ----------------------------------------------------------------------------
# Test whether OS is prior to any specified version

function IsOSBefore()
{
	local testMajor=$1
	local testMinor=$2
	local testPoint=$3
	
	if [ -z "${testMajor}" ]
	then
		return 0
	fi
	
	if [ -z "${testMinor}" ]
	then
		testMinor=0
	fi
	if [ -z "${testPoint}" ]
	then
		testPoint=0
	fi
	
	local IS_PRE=1
	if [ -x "/usr/bin/sw_vers" ]
	then
		local _V=`/usr/bin/sw_vers | grep ProductVersion | sed -e 's/ProductVersion:[^0-9]*//'`
		local maj=`echo ${_V} | sed -e 's/\..*//'`
		local min=`echo ${_V} | sed -e 's/[0-9]*\.//' -e 's/\..*//'`
		# TODO - extract point version if available, default to 0
		
		# echo V ${_V}
		# echo "MAJ '${maj}'"
		# echo "MIN '${min}'"
		
		# TODO - test against point version if available

		if  [ ${maj} -gt ${testMajor} ]
		then
			IS_PRE=0
		elif [[ ${maj} -eq ${testMajor} && ${min} -ge ${testMinor} ]]
		then
			IS_PRE=0
		fi
	fi
	return ${IS_PRE}
}
	